#include <stdafx.h>
#include "MaterialTemplateGenerator.h"
#include <LitStream.h>
#include <LitEditorPrerequisites.h>

namespace Lit
{
	namespace Editor
	{
		namespace Material
		{
			TemplateGenerator::TemplateGenerator( const std::string &filename_with_ext, const std::string &author )
				: mPath(filename_with_ext)
				, mAuthor( author )
			{
			}
			TemplateGenerator::~TemplateGenerator()
			{
			}
			const std::string& TemplateGenerator::getAuthor() const{ return mAuthor; }
			std::string TemplateGenerator::getType() const{ return mPath.extension(); }
			std::string TemplateGenerator::getName() const{ return mPath.fileName( false ); }
			std::string TemplateGenerator::getFileName() const{ return mPath.fileName( false ); }

			std::string TemplateGenerator::generateMaterial( const std::string &base_texture )
			{
				QString ret;
				ret += "// Material Automatically Generated\n";
				ret += "// Version: %1\n";
				ret += "// Name: %2\n";
				ret += "// Author: %3\n";
				ret += "//\n";
				ret += "\n";
				ret += "material %2\n";
				ret += "{\n";
				ret += "    technique tech0\n";
				ret += "    {\n";
				ret += "        pass pass0\n";
				ret += "        {\n";
				ret += "            texture_unit\n";
				ret += "            {\n";
				ret += "                texture %4\n";
				ret += "            }\n";
				ret += "        }\n";
				ret += "    }\n";
				ret += "}\n";
				return FROM_QT(ret.arg(TO_QT(PROJECT_VERSION_STRING))
						.arg(TO_QT(getName()))
						.arg(TO_QT(mAuthor))
						.arg(TO_QT(base_texture)));
			}
			std::string TemplateGenerator::generateProgram( ProgramDef def )
			{
				QString vert, frag, mat;
				vert = "// Shader Program Automatically Generated\n";
				vert += "// Version: %1\n";
				vert += "// Name: %2\n";
				vert += "// Author: %3\n";
				vert += "//\n";
				vert += "\n";
				vert = vert.arg(TO_QT(PROJECT_VERSION_STRING))
					.arg(TO_QT(def.shaderName))
					.arg(TO_QT(def.headers.author));
				if( def.hasVertex || def.hasPixel )
				{
					mat = "material %1\n";
					mat += "{\n";
					mat += "    technique tech0\n";
					mat += "    {\n";
					mat += "        pass pass0\n";
					mat += "        {\n";
					if( def.hasVertex ) mat += "            vertex_program_ref "+TO_QT(def.vertexShader.name)+"\n";
					if( def.hasPixel ) mat += "            fragment_program_ref "+TO_QT(def.pixelShader.name)+"\n";
					mat += "        }\n";
					mat += "    }\n";
					mat += "}\n";
					mat = mat.arg(TO_QT(def.shaderName));
				}
				if( def.hasVertex )
				{
					vert += "vertex_program %1_VP %2\n";
					vert += "{\n";
					vert += "    source %1.%2\n";
					vert += "    entry_point %4\n";
					vert += "    profiles %3\n";
					vert += "\n";
					vert += "    default_params\n";
					vert += "    {\n";
					vert += "    }\n";
					vert += "}\n\n";
					vert = vert.arg(TO_QT(def.vertexShader.name))
						.arg(TO_QT(def.vertexShader.language))
						.arg(TO_QT(def.vertexShader.profile))
						.arg(TO_QT(def.vertexShader.entryPoint));
				}
				if( def.hasPixel )
				{
					frag = "fragment_program %1_FP %2\n";
					frag += "{\n";
					frag += "    source %1.%2\n";
					frag += "    entry_point %4\n";
					frag += "    profiles %3\n";
					frag += "\n";
					frag += "    default_params\n";
					frag += "    {\n";
					frag += "    }\n";
					frag += "}\n";
					frag = frag.arg(TO_QT(def.pixelShader.name))
						.arg(TO_QT(def.pixelShader.language))
						.arg(TO_QT(def.pixelShader.profile))
						.arg(TO_QT(def.pixelShader.entryPoint));
				}
					
				return FROM_QT(vert+frag);
			}
			std::string TemplateGenerator::generateCompositor( )
			{
				String ret;
				
				ret("// Compositor Automatically Generated\n");
				ret("// Version: ")(PROJECT_VERSION_STRING)("\n");
				ret("// Name: ")(getName())("\n");
				ret("// Author: ")(mAuthor)("\n");
				ret("//\n");
				ret("\n");
ret << "compositor Glass\
{\
    technique\
    {\
        texture rt0 target_width target_height PF_R8G8B8\
		\
        target rt0 { input previous }\
		\
        target_output\
        {\
            // Start with clear output\
            input none\
			\
            pass render_quad\
            {\
                material Ogre/Compositor/GlassPass\
                input 0 rt0\
            }\
        }\
    }\
}\
";
				return ret.str();
			}
			std::string TemplateGenerator::generateParticle( )
			{
				String ret;
				ret("// Particles Automatically Generated\n");
				ret("// Version: ")(PROJECT_VERSION_STRING)("\n");
				ret("// Name: ")(getName())("\n");
				ret("// Author: ")(mAuthor)("\n");
				ret("//\n");
				ret("\n");
				ret << "// A sparkly purple fountain\n"
<< "particle_system Examples/PurpleFountain\n"
<< "{\n"
<< "    material        Examples/Flare2\n"
<< "    particle_width  20\n"
<< "    particle_height 40"
<< "    cull_each       false\n"
<< "    quota           10000\n"
<< "    billboard_type  oriented_self\n"
<< "    \n"
<< "    // Area emitter\n"
<< "    emitter Point\n"
<< "    {\n"
<< "        angle           15\n"
<< "        emission_rate   75\n"
<< "        time_to_live    3\n"
<< "        direction       0 1 0\n"
<< "        velocity_min    250\n"
<< "        velocity_max    300\n"
<< "        colour_range_start  0 0 0\n"
<< "        colour_range_end    1 1 1\n"
<< "    }\n"
<< "\n\n"
<< "    // Gravity\n"
<< "    affector LinearForce\n"
<< "    {\n"
<< "        force_vector      0 -100 0\n"
<< "        force_application add\n"
<< "    }\n"
<< "\n\n"
<< "    // Fader\n"
<< "    affector ColourFader\n"
<< "    {\n"
<< "        red -0.25\n"
<< "        green -0.25\n"
<< "        blue -0.25\n"
<< "    }\n"
<< "}\n";
				return ret.str();
			}
			std::string TemplateGenerator::generateVertexShader( const std::string &lang, const std::string &entry_point )
			{
				QString ret;
				ret = "// Vertex Shader Automatically Generated\n";
				ret += "// Version: %1\n";
				ret += "// Name: %2\n";
				ret += "// Author: %3\n";
				ret += "// Language: %4\n";
				ret += "// Entry Point: %5\n";
				ret += "//\n";
				ret += "\n";
				if( lang == "cg" )
				{
					ret += "float4 %5\n";
ret += "(\n";
ret += "    in float4 p: POSITION,\n";
ret += "    uniform float4x4 wvp\n";
ret += ") : POSITION\n";
ret += "{\n";
ret += "   return mul( pos, wvp );\n";
ret += "}\n";
				}
				ret = ret.arg(TO_QT(PROJECT_VERSION_STRING))
						.arg(TO_QT(getName()))
						.arg(TO_QT(getAuthor()))
						.arg(TO_QT(lang))
						.arg(TO_QT(entry_point));
				return FROM_QT(ret);
			}
			std::string TemplateGenerator::generatePixelShader( const std::string &lang, const std::string &entry_point )
			{
				QString ret;
				ret = "// Pixel Shader Automatically Generated\n";
				ret += "// Version: %1\n";
				ret += "// Name: %2\n";
				ret += "// Author: %3\n";
				ret += "// Language: %4\n";
				ret += "// Entry Point: %5\n";
				ret += "//\n";
				ret += "\n";
				if( lang == "cg" )
				{
					ret += "float4 %5\n";
ret += "(\n";
ret += "    in float2 texCoord: TEXCOORD0,\n";
ret += "\n";
ret += "    uniform sampler baseTex : register(s0),\n";
ret += "\n";
ret += "    uniform float uv\n";
ret += ") : COLOR\n";
ret += "{\n";
ret += "   float4 base = tex2D(baseTex, texCoord*uv);\n";
ret += "   return base;\n";
ret += "}\n";
				}
				ret = ret.arg(TO_QT(PROJECT_VERSION_STRING))
						.arg(TO_QT(getName()))
						.arg(TO_QT(getAuthor()))
						.arg(TO_QT(lang))
						.arg(TO_QT(entry_point));
				return FROM_QT(ret);
			}
		};
	};
};